/* 
   Copyright 2012 Ryne Okimoto

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package model;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;

import recipe.RecipeData;

import manager.FileManager;

import dlldynamicset.DLLDynamicSet;

/**
 * Class - DataManagerModel
 * Description - The data model for the viewcontrollers
 * @author Ryne Okimoto
 */
public class DataManagerModel {

	private static final String ROOT_DIRECTORY = "./rcp_db";
	private static final String RCP_DIRECTORY = ROOT_DIRECTORY + "/Rcp_Files";
	private static final String IMG_DIRECTORY = ROOT_DIRECTORY + "/Img_Files";
	
	private File rootDirectory;
	private File recipeDirectory;
	private File imageDirectory;
	private FileManager currentFileManager;
	private DirectoryStream<Path> recipeStream;
	
	private DLLDynamicSet<FileManager, String> recipeDataSet = null;
	
	private Iterator<FileManager> modelIterator;
	
	/**
	 * Constructor
	 */
	public DataManagerModel(){
		
		recipeDataSet = new DLLDynamicSet<FileManager, String>();
		currentFileManager = null;
		
		rootDirectory = new File(ROOT_DIRECTORY);
		recipeDirectory = new File(RCP_DIRECTORY);
		imageDirectory = new File(IMG_DIRECTORY);
		
		// Create file system only if it doesn't exist
		if(!checkDirectoryExistence()){
			rootDirectory.mkdir();
			recipeDirectory.mkdir();
			imageDirectory.mkdir();
		}
		
		try{
			recipeStream = Files.newDirectoryStream(Paths.get(RCP_DIRECTORY));
		}
		catch(IOException io){
			io.printStackTrace();
			io.getMessage();
		}
		
		readFileDirectory();
		modelIterator = recipeDataSet.iterator();
		
	} // constructor
	
	/**
	 * Method - isDataStructureInitialized
	 * Description - Checks the data structure
	 * @return True - Returns if the data structure is initialized
	 * @return False - Returns if the data structure is null
	 */
	public boolean isDataStructureInitialized(){
		return recipeDataSet != null;
	}
	
	/**
	 * 
	 * @return
	 */
	public int getDataSetSize(){
		return recipeDataSet.size();
	}
	
	/**
	 * Method - readFileDirectory
	 * Description - Reads data from recipe directory 
	 * and loads into data set
	 * @return void
	 */
	private void readFileDirectory(){
		File tempFile = null;
		String fileName = null;
		
		for(Path file : recipeStream){
			tempFile = file.toFile();
			fileName = tempFile.getName();
			if(fileName.endsWith(".rcp")){
				recipeDataSet.insertObject(new FileManager(fileName, tempFile), fileName);
			}
		}
	}
	
	/**
	 * Method - checkDirectoryExistence
	 * Description - Verifies that recipe filesystem is created
	 * @return True - Returns if filesystem exists
	 * @return False - Returns if filesystem does not exist
	 */
	private boolean checkDirectoryExistence(){
		return Files.exists(Paths.get(ROOT_DIRECTORY)) && 
			   Files.exists(Paths.get(RCP_DIRECTORY)) &&
			   Files.exists(Paths.get(IMG_DIRECTORY));
	}
	
	/**
	 * Method - addFileManager
	 * Description - Adds a new FileManager
	 * @param recipeName
	 * @param category
	 * @param ingredients
	 * @param instructions
	 * @return True - Returns if addition succeeds
	 * @return False - Returns if addition fails
	 */
	public boolean addFileManager
		(String recipeName, String category, String ingredients, 
		String instructions, String tags, String image){

		boolean addIsSuccessful = false;
		
		// Create manager
		FileManager addManager = new FileManager(recipeName + ".rcp");
		addIsSuccessful = addManager.createRecipe(
				recipeName, category, ingredients, instructions, image, tags);
		
		// Add manager to collection
		if(addIsSuccessful){
			recipeDataSet.insertObject(addManager, recipeName);
		}
		
		return addIsSuccessful;
	}
	
	/**
	 * Method - setCurrentFileManager
	 * Description - Sets a reference to the current FileManager being used
	 * @param fm
	 * @return void
	 */
	public void setCurrentFileManager(FileManager fm){
		this.currentFileManager = fm;
	}
	
	/**
	 * Method - getCurrentFileManager
	 * Description - Gets the reference to the FileManager being used
	 * @return FileManager - the reference to the FileManager
	 */
	public FileManager getCurrentFileManager(){
		return currentFileManager;
	}
	
	/**
	 * Method - modifyFileManager
	 * Description - Changes the RecipeData object of the current FileManager
	 * @param recipeName
	 * @param category
	 * @param ingredients
	 * @param instructions
	 * @param tags
	 * @param image
	 * @return True - Returns if data is modified
	 * @return False - Returns if data is not modified
	 */
	public boolean modifyFileManager
		(String recipeName, String category, String ingredients, 
		String instructions, String tags, String image){
		
		boolean isModified = false;
		RecipeData tempData = currentFileManager.getData();
		
		// If recipe name changes, change filename
		if(!recipeName.equals(tempData.getRecipeName())){
			currentFileManager.resetFile(recipeName + ".rcp");
		}
		
		if(tempData != null){
			tempData.setRecipeName(recipeName);
			tempData.setCategory(category);
			tempData.setListOfIngredients(ingredients);
			tempData.setInstructions(instructions);
			tempData.setTags(tags);
			tempData.setImageFileName(image);
			
			isModified = true;
		}
		
		return isModified;
	}
	
	/**
	 * Unit tester
	 * @param args
	 */
	public static void main(String[] args){
		System.out.println(
				"*** DataManagerModel Unit Test ***\n\n" +
				"Creating DataManagerModel object and calling constructor...\n");
		
		DataManagerModel testModel = new DataManagerModel();
		
		System.out.println("Printing FileManagers...");
		while(testModel.modelIterator.hasNext()){
			System.out.println(testModel.modelIterator.next().createString());
		}
	} // main

} // DataManagerModel
